package com.hup.winHolderService.ws.util;

import lombok.extern.slf4j.Slf4j;

import javax.websocket.RemoteEndpoint;
import javax.websocket.Session;
import java.lang.reflect.Field;
import java.net.InetSocketAddress;

/**
 * https://blog.csdn.net/RHWRH/article/details/123809926
 */
@Slf4j
public class WebSocketUtil {

    /**
     * 获取ip
     * 未验证公网情况...
     */
    public static String getRemoteAddress(Session session) {
        if (session == null) {
            return null;
        }
        RemoteEndpoint.Async async = session.getAsyncRemote();

        ////在Tomcat 8.0.x版本有效
        //InetSocketAddress addr0 = (InetSocketAddress) getFieldInstance(async,"base#sos#socketWrapper#socket#sc#remoteAddress");
        //System.out.println("clientIP0" + addr0);

        //在Tomcat 8.5以上版本有效
        InetSocketAddress address = (InetSocketAddress) getFieldInstance(async, "base#socketWrapper#socket#sc#remoteAddress");
        if (address == null) return "";
        return address.getAddress().toString().replaceAll("/", "");
    }

    @SuppressWarnings("SameParameterValue")
    private static Object getFieldInstance(Object obj, String fieldPath) {
        String[] fields = fieldPath.split("#");
        for (String field : fields) {
            obj = getField(obj, obj.getClass(), field);
            if (obj == null) {
                return "";
            }
        }
        return obj;
    }

    private static Object getField(Object obj, Class<?> clazz, String fieldName) {
        for (; clazz != Object.class; clazz = clazz.getSuperclass()) {
            try {
                Field field;
                field = clazz.getDeclaredField(fieldName);
                field.setAccessible(true);
                return field.get(obj);
            } catch (Exception e) {
                //继续 getSuperclass
            }
        }
        return "";
    }
}